package com.ray.system.api;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ray.common.SysMsgCodeConstant;
import com.ray.system.builder.CommonPageBuilder;
import com.ray.system.builder.OrgTreeBuilder;
import com.ray.system.builder.OrganizationBuilder;
import com.ray.system.check.OrganizationCheck;
import com.ray.system.service.SysOrganizationService;
import com.ray.system.service.compose.CompanyService;
import com.ray.system.table.TreeUtil;
import com.ray.system.table.dto.OrganizationQueryDTO;
import com.ray.system.table.entity.SysOrganization;
import com.ray.system.table.params.organization.OrganizationCreateParams;
import com.ray.system.table.params.organization.OrganizationEditParams;
import com.ray.system.table.params.organization.OrganizationQueryParams;
import com.ray.system.table.vo.organization.OranizationTreeVO;
import com.ray.system.table.vo.organization.OrganizationVO;
import com.ray.validate.support.utils.ValidateUtil;
import com.ray.woodencreate.beans.LoginUser;
import com.ray.woodencreate.enums.YesOrNoEnum;
import com.ray.woodencreate.exception.BusinessExceptionFactory;
import com.ray.woodencreate.page.CommonPage;
import com.ray.woodencreate.result.MsgCodeConstant;
import com.ray.woodencreate.result.Result;
import com.ray.woodencreate.result.ResultFactory;
import com.ray.woodencreate.util.Assert;
import com.ray.woodencreate.util.LogInUserUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author bo shen
 * @Description: 组织相关服务
 * @Class: OrganizationApi
 * @Package com.ray.system.api
 * @date 2020/5/28 12:38
 * @Organization <p>Ray快速开发平台</p>
 * @updateRecord time(修改时间)  author(修改人)   desc(修改内容)
 */
@Service
@Slf4j
public class OrganizationApi {

    @Autowired
    private SysOrganizationService sysOrganizationService;
    @Autowired
    private CompanyService companyService;

    /**
     * 查询部门列表信息 分页  非删除的
     *
     * @param queryParams
     * @return
     */
    public Result<IPage<OrganizationVO>> pageOrganizations(CommonPage<OrganizationQueryParams, Page<OrganizationVO>> queryParams) {
        Assert.notNull(queryParams, SysMsgCodeConstant.Error.ERR10000001);
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        CommonPageBuilder<OrganizationQueryDTO, SysOrganization> commonPageBuilder = new CommonPageBuilder<>(OrganizationQueryDTO.class);
        commonPageBuilder.appendEntity(queryParams.getEntity()).appendQuery(queryParams.getQuery()).appendPage(queryParams.getPage());
        IPage<SysOrganization> page = sysOrganizationService.page(commonPageBuilder.bulid(), loginUser);
        List<SysOrganization> Organizations = page.getRecords();
        //结果对象
        IPage<OrganizationVO> pageList = new Page<>();
        pageList.setTotal(page.getTotal());
        pageList.setCurrent(page.getCurrent());
        pageList.setSize(page.getSize());
        //查询到结果 数据转换
        if (ObjectUtil.isNotNull(Organizations)) {
            pageList.setRecords(Organizations.stream().map(sysOrganization -> {
                OrganizationVO OrganizationVO = new OrganizationVO();
                BeanUtil.copyProperties(sysOrganization, OrganizationVO);
                return OrganizationVO;
            }).collect(Collectors.toList()));
        } else {
            pageList.setRecords(new ArrayList<>());
        }
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, pageList);
    }

    /**
     * 查询部门列表信息--启用的部门
     *
     * @param queryParams
     * @return
     */
    public Result<List<OrganizationVO>> queryOrganizations(OrganizationQueryParams queryParams) {
        Assert.notNull(queryParams, SysMsgCodeConstant.Error.ERR10000001);
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        OrganizationQueryDTO queryDTO = new OrganizationQueryDTO();
        BeanUtil.copyProperties(queryParams, queryDTO);
        queryDTO.setStatus(YesOrNoEnum.YES.getValue());
        List<SysOrganization> Organizations = sysOrganizationService.list(queryDTO, loginUser);
        //查询对象
        List<OrganizationVO> list = new ArrayList<>();
        if (ObjectUtil.isNotNull(Organizations)) {
            list = Organizations.stream().map(sysOrganization -> {
                OrganizationVO OrganizationVO = new OrganizationVO();
                BeanUtil.copyProperties(sysOrganization, OrganizationVO);
                return OrganizationVO;
            }).collect(Collectors.toList());
        }
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, list);
    }


    /**
     * 创建部门
     *
     * @param createParams 创建对象
     * @return Result
     */
    @Transactional
    public Result<String> createOrganization(OrganizationCreateParams createParams) {
        ValidateUtil.validate(createParams);
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();

        if(StrUtil.isBlank(createParams.getParentDeptCode()) || StrUtil.equals(loginUser.getCompanyCode(),createParams.getParentDeptCode())){
            createParams.setParentDeptCode(loginUser.getCompanyCode());
        }else{
            //校验上级部门是否存在
            SysOrganization paerntOrg = sysOrganizationService.queryOrganizationByOrganizationCode(createParams.getParentDeptCode(), loginUser);
            new OrganizationCheck(paerntOrg).checkNull(SysMsgCodeConstant.Error.ERR10000007);
        }
        //判断OrganizationKey是否存在
        SysOrganization sysOrganization = sysOrganizationService.queryOrganizationByOrganizationName(createParams.getDeptName(),loginUser.getCompanyCode());
        new OrganizationCheck(sysOrganization).checkOrganizationName(null,SysMsgCodeConstant.Error.ERR10000003);
        OrganizationBuilder OrganizationBuilder = new OrganizationBuilder();
        OrganizationBuilder.append(createParams).appendStatus(YesOrNoEnum.YES.getValue()).appendCreate(loginUser).appendCompanyCode(loginUser.getCompanyCode());
        //保存部门信息
        if (!sysOrganizationService.save(OrganizationBuilder.bulid())) {
            log.info("保存部门接口异常,参数:{}", JSON.toJSONString(OrganizationBuilder.bulid()));
            throw BusinessExceptionFactory.newException(MsgCodeConstant.Error.ERR00000001);
        }
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000001, OrganizationBuilder.getCode());
    }

    /**
     * 编辑部门
     *
     * @param editParams 编辑对象
     * @return Result
     */
    @Transactional
    public Result<String> editOrganization(OrganizationEditParams editParams) {
        ValidateUtil.validate(editParams);
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        //判断OrganizationKey是否存在
        SysOrganization sysOrganization = sysOrganizationService.queryOrganizationByOrganizationName(editParams.getDeptName(),loginUser.getCompanyCode());
        new OrganizationCheck(sysOrganization).checkOrganizationName(editParams.getDeptCode(),SysMsgCodeConstant.Error.ERR10000003);
        OrganizationBuilder OrganizationBuilder = new OrganizationBuilder();
        OrganizationBuilder.append(editParams).appendEdit(loginUser);
        //编辑部门信息
        if (!sysOrganizationService.edit(OrganizationBuilder.bulid(), loginUser)) {
            log.info("编辑部门接口异常,参数:{}", JSON.toJSONString(OrganizationBuilder.bulid()));
            throw BusinessExceptionFactory.newException(MsgCodeConstant.Error.ERR00000001);
        }
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000001, editParams.getDeptCode());
    }


    /**
     * 删除部门
     *
     * @param organizationCode 部门编码
     * @return Result
     */
    @Transactional
    public Result<String> deleteOrganization(String organizationCode) {
        ValidateUtil.hasLength(organizationCode,"参数[organizationCode]不能为空");
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        //判断是否有子部门
        Integer childConpanyCount = sysOrganizationService.countChildOrganization(organizationCode);
        //获取权限信息
        SysOrganization sysOrganization = sysOrganizationService.queryOrganizationByOrganizationCode(organizationCode, loginUser);
        new OrganizationCheck(sysOrganization).checkNull(SysMsgCodeConstant.Error.ERR10000002).checkNotHasChild(childConpanyCount,SysMsgCodeConstant.Error.ERR10000004);
        OrganizationBuilder OrganizationBuilder = new OrganizationBuilder();
        OrganizationBuilder.appendCode(organizationCode).appendEdit(loginUser).delete();
        //删除部门信息
        if (!sysOrganizationService.edit(OrganizationBuilder.bulid(), loginUser)) {
            log.info("删除部门接口异常,参数:{}", JSON.toJSONString(OrganizationBuilder.bulid()));
            throw BusinessExceptionFactory.newException(MsgCodeConstant.Error.ERR00000001);
        }
        //删除部门相关 关联信息
        companyService.deleteLink(organizationCode,loginUser);
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000001, organizationCode);
    }

    /**
     * 开启部门
     *
     * @param organizationCode 部门编码
     * @return Result
     */
    @Transactional
    public Result<String> openOrganization(String organizationCode) {
        ValidateUtil.hasLength(organizationCode,"参数[organizationCode]不能为空");
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        //获取权限信息
        SysOrganization sysOrganization = sysOrganizationService.queryOrganizationByOrganizationCode(organizationCode, loginUser);
        new OrganizationCheck(sysOrganization).checkNull(SysMsgCodeConstant.Error.ERR10000002);
        OrganizationBuilder OrganizationBuilder = new OrganizationBuilder();
        OrganizationBuilder.appendCode(organizationCode).appendEdit(loginUser).open();
        //开启部门信息
        if (!sysOrganizationService.edit(OrganizationBuilder.bulid(), loginUser)) {
            log.info("开启部门接口异常,参数:{}", JSON.toJSONString(OrganizationBuilder.bulid()));
            throw BusinessExceptionFactory.newException(MsgCodeConstant.Error.ERR00000001);
        }
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000001, organizationCode);
    }

    /**
     * 开启部门
     *
     * @param organizationCode 部门编码
     * @return Result
     */
    @Transactional
    public Result<String> closeOrganization(String organizationCode) {
        ValidateUtil.hasLength(organizationCode,"参数[OrganizationCode]不能为空");
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        //获取权限信息
        SysOrganization sysOrganization = sysOrganizationService.queryOrganizationByOrganizationCode(organizationCode, loginUser);
        new OrganizationCheck(sysOrganization).checkNull(SysMsgCodeConstant.Error.ERR10000002);
        OrganizationBuilder OrganizationBuilder = new OrganizationBuilder();
        OrganizationBuilder.appendCode(organizationCode).appendEdit(loginUser).close();
        //关闭部门信息
        if (!sysOrganizationService.edit(OrganizationBuilder.bulid(), loginUser)) {
            log.info("关闭部门接口异常,参数:{}", JSON.toJSONString(OrganizationBuilder.bulid()));
            throw BusinessExceptionFactory.newException(MsgCodeConstant.Error.ERR00000001);
        }
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000001, OrganizationBuilder.getCode());
    }

    /**
     * 部门详情
     *
     * @param organizationCode 部门编码
     * @return Result
     */
    public Result<OrganizationVO> viewOrganization(String organizationCode) {
        ValidateUtil.hasLength(organizationCode,"参数[organizationCode]不能为空");
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        //获取权限信息
        SysOrganization sysOrganization = sysOrganizationService.queryOrganizationByOrganizationCode(organizationCode, loginUser);
        new OrganizationCheck(sysOrganization).checkNull(SysMsgCodeConstant.Error.ERR10000002);
        OrganizationVO organizationVO = new OrganizationVO();
        BeanUtil.copyProperties(sysOrganization, organizationVO);
        if(StrUtil.equals(sysOrganization.getParentDeptCode(),loginUser.getCompanyCode())){
            organizationVO.setParentDeptName(loginUser.getCompanyName());
        }else {
            //查询上级部门信息
            SysOrganization parentOrganization = sysOrganizationService.queryOrganizationByOrganizationCode(sysOrganization.getParentDeptCode(), loginUser);
            if(ObjectUtil.isNotNull(parentOrganization)){
                organizationVO.setParentDeptName(parentOrganization.getDeptName());
            }
        }
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, organizationVO);
    }

    public Result<List<OranizationTreeVO>> tree( OrganizationQueryParams queryParams) {
        LoginUser loginUser = LogInUserUtil.get();
        OrganizationQueryDTO queryDTO = new OrganizationQueryDTO();
        BeanUtil.copyProperties(queryParams, queryDTO);
        List<SysOrganization> Organizations = sysOrganizationService.list(queryDTO, loginUser);
        List<OranizationTreeVO> orgTreeList = Organizations.stream().map(sysOrganization -> {
            return new OrgTreeBuilder().append(sysOrganization).bulid();
        }).sorted(Comparator.comparingInt(oranization ->{
            return ObjectUtil.isNotNull(oranization.getIndexSort())? oranization.getIndexSort():0;
        })).collect(Collectors.toList());
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, TreeUtil.bulidOrg(orgTreeList, loginUser.getCompanyCode()));
    }
}
